package com.w.picture.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * Swagger 启动时打印访问地址
 *
 * @author wzp
 * @since 2024/12/14
 */
@Slf4j
@Configuration
public class SwaggerPrintConfig implements ApplicationListener<WebServerInitializedEvent> {

    /**
     * 实现 ApplicationListener 接口
     * 面向接口编程: 实现ApplicationListener接口是一种更为传统的面向接口编程的方式。你需要创建一个类并实现该接口，然后重写onApplicationEvent方法。
     * 单一职责: 每个实现了ApplicationListener接口的类只能监听一种特定类型的事件。如果你想监听多种类型的事件，则需要为每种事件创建一个单独的监听器类。
     * 明确意图: 明确地表达了类的意图，即它是一个专门用来处理某种事件的监听器。
     * 手动注册: 在某些情况下，你可能需要手动将监听器注册到Spring上下文中（不过通常Spring Boot会自动为你做这件事）。
     * <p>
     * WebServerInitializedEvent:
     * 触发时间: 当嵌入式web服务器（如Tomcat、Jetty）已经启动并初始化完毕时触发。
     * 适用场景: 如果你需要尽早地访问web服务器信息（例如端口号），这个事件是一个合适的选择。它在所有bean被加载之后但在应用程序完全准备好处理请求之前触发。
     * 优点: 可以更早地获取到web服务器的信息。
     * 缺点: 此时应用程序可能还未完全准备就绪，一些依赖或服务可能还没有完成初始化。
     *
     * @param event the event to respond to
     */
    @Override
    public void onApplicationEvent(WebServerInitializedEvent event) {
        try {
            // 获取IP地址
            InetAddress inetAddress = InetAddress.getLocalHost();
            String hostAddress = inetAddress.getHostAddress();

            // 获取端口号
            int port = event.getWebServer().getPort();


            // 打印启动信息和Swagger UI地址
            log.info("项目启动成功！访问地址: http://{}:{}", "127.0.0.1", port);
            log.info("Knife4j UI: http://{}:{}/doc.html", "127.0.0.1", port);

        } catch (UnknownHostException e) {
            log.error("无法获取主机地址", e);
        }
    }
}
